home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 18 / CU Amiga Magazine's Super CD-ROM 18 (1997)(EMAP Images)(GB)[!][issue 1998-01].iso / CUCD / Programming / AmigaE / Src / OOmodules / list / elist.e < prev    next >
Encoding:
Text File  |  1996-09-10  |  10.0 KB  |  514 lines

  1. OPT MODULE
  2.  
  3. MODULE  'oomodules/object'
  4.  
  5. EXPORT OBJECT elist OF object
  6. /****** elist/elist ******************************
  7.  
  8.     NAME
  9.         elist of object
  10.  
  11.     PURPOSE
  12.         Handles E's own lists in a more dynamic manner. When the limit of
  13.         items is reached the list is simply expanded.
  14.  
  15.     ATTRIBUTES
  16.         list:PTR TO LONG -- Normal E list.
  17.  
  18.         itemCount:LONG -- How many items actually are in the list. Note that
  19.             this is NOT the length of the list. This attribute points at the
  20.             next free slot to put a value in.
  21.  
  22.         hunkSize:LONG -- The number of items the list is expanded by if
  23.             necessary.
  24.  
  25.     SEE ALSO
  26.         object/object
  27. ********/
  28.   list:PTR TO LONG
  29.   itemCount
  30.   hunkSize
  31. ENDOBJECT
  32.  
  33. PROC init() OF elist
  34. /****** elist/init ******************************
  35.  
  36.     NAME
  37.         init() of elist -- Initialization of the object.
  38.  
  39.     SYNOPSIS
  40.         elist.init()
  41.  
  42.     FUNCTION
  43.         Sets the hunk size to the initial value (currently this is 16, that
  44.         may change) and allocates a list that can holg that much items.
  45.  
  46.     SEE ALSO
  47.         elist
  48.  
  49. ********/
  50.  
  51.   self.hunkSize := 16
  52.   self.list := List(self.hunkSize)
  53.   SetList(self.list, self.hunkSize)
  54.  
  55. ENDPROC
  56.  
  57. PROC select(optionlist, index) OF elist
  58. /****** elist/select ******************************
  59.  
  60.     NAME
  61.         select() of elist -- Selection of action via tag list.
  62.  
  63.     SYNOPSIS
  64.         elist.select(LONG, LONG)
  65.  
  66.         elist.select(optionlist, index)
  67.  
  68.     FUNCTION
  69.         Recognized tags are:
  70.             "set"  --  next item is a normal E list. The object is set to
  71.                 hold that list. See elist/set().
  72.  
  73.     INPUTS
  74.         optionlist:LONG -- list of options
  75.  
  76.         index:LONG -- index of option list
  77.  
  78.     EXAMPLE
  79.         see object/select for an example of how select() works in general.
  80.  
  81.     SEE ALSO
  82.         elist/set()
  83.  
  84. ********/
  85. DEF item
  86.  
  87.   item:=ListItem(optionlist,index)
  88.  
  89.   SELECT item
  90.  
  91.     CASE "set"
  92.  
  93.       INC index
  94.       self.set(ListItem(optionlist,index))
  95.  
  96.   ENDSELECT
  97.  
  98. ENDPROC index
  99.  
  100. PROC set(elist) OF elist
  101. /****** elist/set ******************************
  102.  
  103.     NAME
  104.         set() of elist -- Sets the contents of the list.
  105.  
  106.     SYNOPSIS
  107.         elist.set(LONG)
  108.  
  109.         elist.set(elist)
  110.  
  111.     FUNCTION
  112.         The object is set to point to the list that is given to the function.
  113.         By calling this function you hand the list over to the object. That
  114.         means that you may not free it unless you remove it from the object
  115.         first. Note that the list is automatically freed when ENDing this
  116.         object.
  117.  
  118.         If the object already holds a list that one is freed first. So if
  119.         you want to remove a list from the object safely after you have passed
  120.         it you may call this function with NIL.
  121.  
  122.     INPUTS
  123.         elist:LONG -- normal E list. May be NIL.
  124.  
  125.     EXAMPLE
  126.  
  127.         -> First allocate it
  128.  
  129.         NEW elist.new()
  130.  
  131.         -> set it
  132.  
  133.         elist.set([1,2,3,42])
  134.  
  135.         -> now free it
  136.         elist.set(NIL)
  137.  
  138.     NOTES
  139.         This function is called when you provide the tag "list" in the option
  140.         list for method new()
  141.  
  142.     SEE ALSO
  143.         elist, new()
  144.  
  145. ********/
  146.  
  147.   IF self.list THEN DisposeLink(self.list)
  148.   self.list := elist
  149.   IF elist THEN self.itemCount := ListLen(self.list) ELSE self.itemCount := 0
  150.  
  151. ENDPROC
  152.  
  153. PROC get() OF elist IS self.list, IF self.list THEN ListLen(self.list) ELSE -1
  154. /****** elist/get ******************************
  155.  
  156.     NAME
  157.         get() of elist -- Get the list and it's length.
  158.  
  159.     SYNOPSIS
  160.         elist.get()
  161.  
  162.     FUNCTION
  163.         Gets you the actual E list and it's length. The list may not have all
  164.         it's items set if it was expanded.
  165.  
  166.     RESULT
  167.         PTR TO LONG -- The E list. NIL if no list is there.
  168.  
  169.         LONG -- The length of the E list. -1 if no list is there.
  170.  
  171.     SEE ALSO
  172.         elist
  173.  
  174. ********/
  175.  
  176. PROC grow() OF elist
  177. /****** elist/grow ******************************
  178.  
  179.     NAME
  180.         grow() of elist -- Expand a list.
  181.  
  182.     SYNOPSIS
  183.         elist.grow()
  184.  
  185.     FUNCTION
  186.         Expands the list by the number of items that is put in the hunkSize
  187.         attribute.
  188.  
  189.     RESULT
  190.         LONG -- -1 if the list could not be expanded. The current list stays
  191.             valid.
  192.  
  193.     EXAMPLE
  194.  
  195.         NEW list.new()
  196.  
  197.         WriteF('Actual lenght of the list is \d.\n', ListLen(list.list))
  198.         list.grow()
  199.         WriteF('Actual lenght of the list is \d.\n', ListLen(list.list))
  200.  
  201.     SEE ALSO
  202.         elist, add()
  203.  
  204. ********/
  205. DEF tempList:PTR TO LONG,
  206.     nuSize
  207.  
  208.   nuSize := ListLen(self.list)+self.hunkSize
  209.   tempList := List(nuSize)
  210.  
  211.   IF tempList = NIL THEN RETURN -1
  212.  
  213.   ListCopy(tempList, self.list, ALL)
  214.   DisposeLink(self.list)
  215.   self.list := tempList
  216.   SetList(self.list,nuSize)
  217.  
  218. ENDPROC
  219.  
  220. PROC add(item) OF elist
  221. /****** elist/add ******************************
  222.  
  223.     NAME
  224.         add() of elist -- Add an item to the list.
  225.  
  226.     SYNOPSIS
  227.         elist.add(LONG)
  228.  
  229.         elist.add(item)
  230.  
  231.     FUNCTION
  232.         Adds an item to the list and expands the list if necessary.
  233.  
  234.     INPUTS
  235.         item:LONG -- Item to add to the list.
  236.  
  237.     RESULT
  238.         LONG -- -1 if expansion of the list failed. The current list stays
  239.             valid.
  240.  
  241.     SEE ALSO
  242.         elist, grow()
  243.  
  244. ********/
  245. DEF list:PTR TO LONG,
  246.     res
  247.  
  248.   list := self.list
  249.  
  250.   res := Mod(self.itemCount+1, self.hunkSize)
  251. ->  WriteF('-- \d\n', res)
  252.   IF (res = 0)
  253.  
  254. ->    WriteF('hafta grow at \d\n', self.itemCount)
  255.     IF self.grow()=-1 THEN RETURN -1
  256. ->    WriteF('grown at \n', self.itemCount)
  257.     list := self.list
  258.   ENDIF
  259.  
  260.   list[self.itemCount] := item
  261.   self.itemCount := self.itemCount+1
  262.  
  263. ENDPROC
  264.  
  265. PROC putAt(item,position) OF elist HANDLE
  266. /****** elist/putAt ******************************
  267.  
  268.     NAME
  269.         putAt() of elist -- Puts an item at a specific position in the list.
  270.  
  271.     SYNOPSIS
  272.         elist.putAt(LONG, LONG)
  273.  
  274.         elist.putAt(item, position)
  275.  
  276.     FUNCTION
  277.         Puts an item in the list at a certain position. Any value that is at
  278.         that position will be overwritten. The list is expanded if necessary.
  279.  
  280.     INPUTS
  281.         item:LONG -- Item to put in the list.
  282.  
  283.         position:LONG -- Position to put it at.
  284.  
  285.     RESULT
  286.         LONG -- -1 if the list could not be expanded. The current list stays
  287.             valid.
  288.  
  289.     SEE ALSO
  290.         elist, grow()
  291.  
  292. ********/
  293.  
  294.   WHILE (position>=ListLen(self.list)) -> while position is out of range
  295.  
  296.     IF (self.grow()=-1) THEN Raise("MEM") -> exit if no memory
  297.  
  298.   ENDWHILE
  299.  
  300.   self.list[position] := item
  301.  
  302. ->  WriteF('put \d at \d.\n', item, position)
  303.  
  304.  
  305. EXCEPT
  306.  
  307.   RETURN -1
  308.  
  309. ENDPROC
  310.  
  311. PROC getFrom(position) OF elist
  312. /****** elist/getFrom ******************************
  313.  
  314.     NAME
  315.         getFrom() of elist -- Get item from a specific position.
  316.  
  317.     SYNOPSIS
  318.         elist.getFrom(LONG)
  319.  
  320.         elist.getFrom(position)
  321.  
  322.     FUNCTION
  323.         Gets the item that's at position in the list.
  324.  
  325.     INPUTS
  326.         position:LONG -- Position to get the item from.
  327.  
  328.     RESULT
  329.         LONG, LONG -- 0, "rnge" if the position was out of range, i.e. if it
  330.             exceeded the list's length.
  331.  
  332.     SEE ALSO
  333.         elist
  334.  
  335. ********/
  336.  
  337.   IF position >= ListLen(self.list) THEN RETURN 0,"rnge"
  338.  
  339.   RETURN self.list[position]
  340.  
  341. ENDPROC
  342.  
  343. PROC end() OF elist
  344. /****** elist/end ******************************
  345.  
  346.     NAME
  347.         end() of elist -- Global destructor.
  348.  
  349.     SYNOPSIS
  350.         elist.end()
  351.  
  352.     FUNCTION
  353.         Disposes the list.
  354.  
  355.     SEE ALSO
  356.         elist
  357.  
  358. ********/
  359.  
  360.   IF self.list THEN DisposeLink(self.list)
  361.  
  362. ENDPROC
  363.  
  364. PROC kill() OF elist
  365. /****** elist/kill ******************************
  366.  
  367.     NAME
  368.         kill() of elist -- END all items and the object.
  369.  
  370.     SYNOPSIS
  371.         elist.kill()
  372.  
  373.     FUNCTION
  374.         Goes through the list and does an END on each if the item is not NIL.
  375.         After that the object itself is ENDed.
  376.  
  377.     NOTES
  378.         Only call this function when you really know what is in the list.
  379.  
  380.     SEE ALSO
  381.         elist
  382.  
  383. ********/
  384. DEF index,
  385.     item
  386.  
  387.   IF self.list = NIL THEN RETURN
  388.  
  389.   FOR index := 0 TO self.itemCount
  390.  
  391.     item := self.list[index]
  392.     IF item THEN END item
  393.  
  394.   ENDFOR
  395.  
  396.   END self
  397.  
  398. ENDPROC
  399.  
  400. PROC strip() OF elist
  401. /****** elist/strip ******************************
  402.  
  403.     NAME
  404.         strip() of elist -- Strip existing list from object.
  405.  
  406.     SYNOPSIS
  407.         elist.strip()
  408.  
  409.     FUNCTION
  410.         Gets you the existing list and initializes the object. The list you
  411.         get can be used ater the object was ENDed. Useful in procs
  412.         when you want to work with the elist object but don't want to return
  413.         this object.
  414.  
  415.     EXAMPLE
  416.  
  417.       PROC passMeAList(passedList)
  418.       DEF elist:PTR TO elist,
  419.           list,
  420.           anyVar
  421.  
  422.           NEW elist.new()
  423.  
  424.           ForAll({anyVar}, passedList, 'IF anyVar=42 THEN elist.add('blue-footed boobie'))
  425.  
  426.          /*
  427.           * We strip the list from the object for outside of this proc
  428.           * nobody should know what object we'rr working with :)
  429.           */
  430.  
  431.           list := elist.strip()
  432.           END elist
  433.  
  434.       ENDPROC list
  435.  
  436.     SEE ALSO
  437.         elist, init()
  438.  
  439. ********/
  440. DEF list
  441.  
  442.   list := self.list
  443.   SetList(list, self.itemCount)
  444.  
  445.   self.list := NIL
  446.   self.itemCount := 0
  447.  
  448.   self.init()
  449.  
  450.   RETURN list
  451.  
  452. ENDPROC
  453.  
  454. PROC find(item) OF elist
  455. DEF index=-1
  456.  
  457.   REPEAT
  458.  
  459.     INC index
  460.  
  461.   UNTIL (self.list[index]=item) OR (index=self.itemCount)
  462.  
  463.   /* WriteF('found at \d.\n', index) */
  464.   IF index = self.itemCount THEN Throw("elis",'item not found') ELSE RETURN index
  465.  
  466. ENDPROC
  467.  
  468. PROC removeFrom(number) OF elist
  469.  
  470.   IF self.list = NIL THEN RETURN
  471.  
  472.   IF self.itemCount
  473.  
  474.     self.list[number] := self.list[self.itemCount-1]
  475.     self.list[self.itemCount-1] := NIL
  476.  
  477.     self.itemCount := self.itemCount-1
  478.  
  479.   ELSE
  480.  
  481.     self.list[0] := NIL
  482.     self.itemCount := 0
  483.  
  484.   ENDIF
  485.  
  486. ENDPROC
  487.  
  488. PROC remove(item) OF elist HANDLE
  489.  
  490.   self.removeFrom(self.find(item))
  491.  
  492. EXCEPT
  493.  
  494.   /* WriteF('Unable to remove item - not in list.\n')*/
  495. ENDPROC
  496.  
  497. PROC setNextFreeSlotAt(position) OF elist HANDLE
  498.  
  499.   WHILE (position>=ListLen(self.list)) -> while position is out of range
  500.  
  501.     IF (self.grow()=-1) THEN Raise("MEM") -> exit if no memory
  502.  
  503.   ENDWHILE
  504.  
  505.   self.itemCount := position
  506.  
  507. EXCEPT
  508.  
  509. ENDPROC
  510. /*EE folds
  511. -1
  512. 5 26 7 21 10 40 13 50 39 41 42 42 91 29 94 18 97 33 100 51 103 11 106 17 109 6 112 11 
  513. EE folds*/
  514.